package com.niodata.dp.web.module.app;

import com.niodata.dp.app.AppInfo;
import com.niodata.dp.app.AppManager;
import com.niodata.dp.app.AppVariable;
import com.niodata.dp.app.VariableManager;
import com.niodata.dp.app.VariableValue;
import com.niodata.dp.core.exception.ErrorCodes;
import com.niodata.dp.core.usermgr.model.UserInfo;
import com.niodata.dp.task.TaskReservedWords;
import com.niodata.dp.task.entity.ParamType;
import com.niodata.dp.web.PageInfo;
import com.niodata.dp.web.module.base.BaseController;
import com.niodata.dp.web.security.ContextUtil;
import java.util.Date;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/v1/app/var")
public class VariableController extends BaseController {

  @Autowired
  @Qualifier("variableManagerImpl")
  private VariableManager variableManager;

  @Autowired
  @Qualifier("appManagerImpl")
  private AppManager appManager;

  /**
   * list variable .
   *
   * @param appId appId
   * @param pageIndex pageIndex
   * @param pageSize pageSize
   * @return object
   */
  @RequestMapping("list")
  public Object list(@RequestParam("appId") String appId,
        @RequestParam(value = "pageIndex", required = false, defaultValue = "1") int pageIndex,
        @RequestParam(value = "pageSize", required = false, defaultValue = "20") int pageSize) {
    UserInfo currentUser = ContextUtil.getCurrentUser();
    List<AppVariable> variableList =
          variableManager
                .getVariables(currentUser.getUserId(), appId, null, pageSize * (pageIndex - 1),
                      pageSize + 1);
    PageInfo pageInfo = new PageInfo();
    pageInfo.setPageIndex(pageIndex);
    pageInfo.setStart((pageIndex - 1) * pageSize + 1);
    if (variableList.size() > pageSize) {
      pageInfo.setStop(pageInfo.getStart() + pageSize);
    } else {
      pageInfo.setStop(pageInfo.getStart() + variableList.size());
    }
    pageInfo.setHasMore(variableList.size() > pageSize);
    return getPagedResult(
          variableList.size() > pageSize ? variableList.subList(0, variableList.size() - 1)
                : variableList, pageInfo);
  }

  /**
   * create variable.
   *
   * @param variable variable
   * @return status
   */
  @RequestMapping(value = "", method = RequestMethod.POST)
  public Object create(@RequestBody AppVariable variable) {
    //createVariable(String appId, VariableType type, String name, String description,
    //String taskName, String job, String param);
    if (TaskReservedWords.isReservedWord(variable.getName())) {
      return getError(400, variable.getName() + " is reserved key word");
    }
    if (variable.getInitValue() != null && variable.getInitValue().toString().length() > 0) {
      variable.setInitValue(
            ParamType.parse(variable.getInitValue().toString(), variable.getParamType()));
    }

    AppInfo appInfo = appManager.getByAppId(variable.getAppId());
    variableManager.createVariable(variable.getAppId(),
          appInfo.getAppCode(),
          variable.getType(),
          variable.getParamType(),
          variable.getName(),
          variable.getDescription(),
          variable.getBindTask(),
          variable.getBindJob(),
          variable.getBindParam(),
          variable.getInitValue());
    return getResult(true);
  }

  /**
   * update variable info.
   *
   * @param variable variable
   * @return success
   */
  @RequestMapping(value = "", method = RequestMethod.PUT)
  public Object update(@RequestBody AppVariable variable) {
    AppVariable appVariable =
          this.variableManager.getVariable(variable.getAppId(), variable.getName());
    appVariable.setBindTask(variable.getBindTask());
    appVariable.setBind(variable.getBindTask() != null);
    appVariable.setBindJob(variable.getBindJob());
    appVariable.setBindParam(variable.getBindParam());
    appVariable.setDescription(variable.getDescription());

    if (null != variable.getCurrentValue()) {
      Object currentValue = variable.getCurrentValue().getValue();
      if (null != currentValue && currentValue.toString().length() > 0) {
        Object obj = ParamType.parse(currentValue.toString(),
              variable.getCurrentValue().getParamType());
        if (null == obj) {
          return getError(ErrorCodes.ERROR_PARAM, "参数类型有误");
        }
        variable.getCurrentValue().setValue(obj);
      }

      VariableValue preCurrentVar = appVariable.getCurrentValue();
      appVariable.setCurrentValue(variable.getCurrentValue());
      appVariable.setPreviousValue(preCurrentVar);
    }

    if (appVariable.getBindTime() == null && appVariable.isBind()) {
      appVariable.setBindTime(new Date());
    }
    if (!appVariable.isBind() && appVariable.getBindTime() != null) {
      appVariable.setBindTime(null);
      appVariable.setInitTime(null);
      appVariable.setUpTime(null);
    } else {
      appVariable.setUpTime(new Date());
    }
    this.variableManager.update(appVariable);
    return getResult(true);
  }

  @RequestMapping(value = "", method = RequestMethod.DELETE)
  public Object delete(@RequestParam("appId") String appId, @RequestParam("name") String name) {
    variableManager.deleteVariable(appId, name);
    return getResult(true);
  }

}
